package com.bckj.fastboot.upms.api.util.dict;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.bckj.fastboot.upms.api.entity.SysDict;
import com.bckj.fastboot.upms.api.util.dict.annotation.Dict;

import java.io.IOException;
import java.util.Objects;

public class DictSerializer extends StdSerializer<Object> implements ContextualSerializer {
    private String type;
    private String genFieldName;

    public DictSerializer() {
        super(Object.class);
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (Objects.isNull(value)) {
            gen.writeObject(value);
            return;
        }
        gen.writeObject(value);
        if (Objects.nonNull(type)) {
            // 通过数据字典类型和value获取name
            String label = getLabel(type, value.toString());
            if (StrUtil.isNotBlank(genFieldName)) {
                gen.writeFieldName(genFieldName);
            } else {
                gen.writeFieldName(gen.getOutputContext().getCurrentName() + "Name");
            }
            gen.writeObject(label);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty beanProperty) throws JsonMappingException {
        if (Objects.isNull(beanProperty)) {
            return prov.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        Dict dict = beanProperty.getAnnotation(Dict.class);
        if (Objects.nonNull(dict)) {
            type = dict.type();
            genFieldName = dict.genFieldName();
            return this;
        }
        return prov.findNullValueSerializer(null);
    }

    private String getLabel(String type,String code) {
        if(code.contains(",")) {
            String[] sa = code.split(",");
            if (sa.length > 1) {
                StringBuilder sb = new StringBuilder();
                for (String str : sa) {
                    // 从缓存中获取字典。如果不行，通过SpringUtil.getBean(); 获取服务处理
                    sb.append(labelFromLoader(type, str)).append("|");
                }
                return sb.substring(0, sb.length() - 1);
            }
        }
        // 从缓存中获取字典。如果不行，通过SpringUtil.getBean(); 获取服务处理
        return labelFromLoader(type, code);
    }

    private String labelFromLoader(String type, String code) {
        return DictResolver.getByCode(type, code).map(SysDict::getValue).orElse(null);
    }
}